package com.chixing.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.chixing.config.AlipayConfig;
import com.chixing.entity.OrderBase;
import com.chixing.entity.Transaction;
import com.chixing.service.IOrderBaseService;
import com.chixing.service.IRefundService;
import com.chixing.service.ITransactionService;
import com.chixing.util.Result;
import com.chixing.annotation.AutoIdempotent; // 假设存在幂等性注解
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author liwenjing
 * @since 2025-10-07
 */
@CrossOrigin
@RestController
@RequestMapping("/refund")
public class RefundController {

    @Autowired
    private IRefundService refundService;
    @Autowired
    private ITransactionService transactionService;
    @Autowired
    private IOrderBaseService orderBaseService;

    /**
     * 支付宝退款接口
     */
    @PostMapping("/refund")
    @AutoIdempotent // 防止重复提交
    @ResponseBody
    public void refund(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        // 获取请求参数
        String orderIdStr = request.getParameter("orderId");
        String refundAmountStr = request.getParameter("refundAmount");
        // 参数校验
        if (orderIdStr == null || orderIdStr.trim().isEmpty()) {
            out.println("{\"error\":\"订单ID不能为空\"}");
            return;
        }

        if (refundAmountStr == null || refundAmountStr.trim().isEmpty()) {
            out.println("{\"error\":\"退款金额不能为空\"}");
            return;
        }

        Integer orderId = Integer.valueOf(orderIdStr);
        BigDecimal refundAmount = new BigDecimal(refundAmountStr);

        try {
            // 获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(
                    AlipayConfig.gatewayUrl,
                    AlipayConfig.app_id,
                    AlipayConfig.merchant_private_key,
                    "json",
                    AlipayConfig.charset,
                    AlipayConfig.alipay_public_key,
                    AlipayConfig.sign_type
            );

            // 设置请求参数
            AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

            // 商户订单号，必填
            OrderBase orderBase = orderBaseService.getOrderById(orderId);
            if (orderBase == null) {
                out.println("{\"error\":\"订单不存在\"}");
                return;
            }

            String out_trade_no = orderBase.getOrderNumber();

            // 需要退款的金额，该金额不能大于订单金额，必填
            BigDecimal orderAmount = orderBase.getFinalPrice();
            if (refundAmount.compareTo(orderAmount) > 0) {
                out.println("{\"error\":\"退款金额不能大于订单金额\"}");
                return;
            }

            // 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
            String out_request_no = UUID.randomUUID().toString();

            // 组装请求参数
            alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                    + "\"refund_amount\":\""+ refundAmount +"\","
                    + "\"out_request_no\":\""+ out_request_no +"\"}");

            // 执行退款请求
            String result = alipayClient.execute(alipayRequest).getBody();

            // 输出结果
            out.println(result);

            // 解析结果并更新本地状态
            if (result.contains("\"code\":\"10000\"")) {
                // 退款成功，更新本地数据
                Result refundResult = refundService.handleRefund(orderId, orderBase.getUserId());
                Transaction transaction = transactionService.getTransactionByOrderId(orderId);
                if (transaction != null) {
                    transaction.setStatues(2); // 2-已退款
                    transaction.setUpdateTime(LocalDateTime.now());
                    transactionService.updateTransaction(transaction);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            out.println("{\"error\":\"退款失败\"}");
        }
    }

}
